package com.supermap.dialogs;

import com.supermap.Helper;
import com.supermap.data.*;
import com.supermap.dialogs.advance.CJDialog;

import javax.swing.*;
import java.awt.*;

public class EntityEncodeDialog extends CJDialog {
    private JComboBox<String> datasourceCmb;
    private JComboBox<String> datasetCmb;

    private Workspace workspace;
    private boolean is3D;

    private ProcessBarDialog processBarDialog;

    public EntityEncodeDialog(Frame owner, String title, boolean modal, Workspace workspace, boolean is3D) {
        super(owner, title, modal, 300, 120, new Object[]{workspace, is3D});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        workspace = (Workspace) args[0];
        is3D = (boolean) args[1];
    }

    @Override
    protected void initializeCore() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridBagLayout());
        add(centerPanel, BorderLayout.CENTER);

        centerPanel.add(new JLabel("数据源:"), new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        datasourceCmb = new JComboBox<>();
        centerPanel.add(datasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        centerPanel.add(new JLabel("数据集:"), new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
        datasetCmb = new JComboBox<>();
        centerPanel.add(datasetCmb, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        Datasources datasources = workspace.getDatasources();
        datasourceCmb.removeAll();
        for (int i = 0; i < datasources.getCount(); i++) {
            Datasource datasource = datasources.get(i);
            datasourceCmb.addItem(datasource.getAlias());
        }

        datasetCmb.removeAll();
        if (datasourceCmb.getItemCount() > 0) {
            String datasourceAlias = (String) datasourceCmb.getSelectedItem();
            Datasource datasource = datasources.get(datasourceAlias);
            Datasets datasets = datasource.getDatasets();
            for (int i = 0; i < datasets.getCount(); i++) {
                Dataset dataset = datasets.get(i);
                if (dataset instanceof DatasetVector) {
                    datasetCmb.addItem(dataset.getName());
                }
            }
        }

        datasourceCmb.addItemListener(e -> {
            String datasourceAlias = (String) e.getItem();
            Datasource datasource = datasources.get(datasourceAlias);
            datasetCmb.removeAll();
            Datasets datasets = datasource.getDatasets();
            for (int i = 0; i < datasets.getCount(); i++) {
                Dataset dataset = datasets.get(i);
                if (dataset instanceof DatasetVector) {
                    datasetCmb.addItem(dataset.getName());
                }
            }
        });
    }

    @Override
    protected void doConfirmCore() {
        if (processBarDialog == null) {
            processBarDialog = new ProcessBarDialog((Frame) getOwner(), "数据集实体编码", true);
            processBarDialog.setValue(0);
        }

        String datasourceAlias = (String) datasourceCmb.getSelectedItem();
        String datasetName = (String) datasetCmb.getSelectedItem();
        Datasource datasource = workspace.getDatasources().get(datasourceAlias);
        DatasetVector datasetVector = (DatasetVector) datasource.getDatasets().get(datasetName);

        int recordCount = datasetVector.getRecordCount();
        FieldInfos fieldInfos = datasetVector.getFieldInfos();
        String defaultEntityEncodeFieldName = is3D ? "Encode3D" : "Encode";
        int tempCount = 1;
        String entityEncodeFieldName = defaultEntityEncodeFieldName;
        for (int i = 0; i < fieldInfos.getCount(); i++) {
            FieldInfo fieldInfo = fieldInfos.get(i);
            if (entityEncodeFieldName.equals(fieldInfo.getName())) {
                entityEncodeFieldName = defaultEntityEncodeFieldName + "_" + tempCount;
                tempCount++;
                i = 0;
            }
        }

        FieldInfo fieldInfo = new FieldInfo(entityEncodeFieldName, FieldType.TEXT);
        int addedFiledInfo = fieldInfos.add(fieldInfo);
        if (addedFiledInfo == 0) {
            JOptionPane.showMessageDialog(this, is3D ? "数据集三维实体编码失败！" : "数据集二维实体编码失败！",
                    is3D ? "数据集三维实体编码" : "数据集二维实体编码", JOptionPane.ERROR_MESSAGE);
            return;
        }

        Recordset recordset = datasetVector.getRecordset(false, CursorType.DYNAMIC);

        String finalEntityEncodeFieldName = entityEncodeFieldName;
        new Thread(() -> {
            try {
                int index = 0;
                do {
                    recordset.edit();
                    Geometry geometry = recordset.getGeometry();
                    if (geometry != null) {
                        String entityEncode = is3D ? SpatialGridCoding.geoEntityEncode3D((Geometry3D) geometry) : SpatialGridCoding.geoEntityEncode(geometry);
                        boolean updatedFieldFlag = recordset.setString(finalEntityEncodeFieldName, entityEncode);
                        if (!updatedFieldFlag) {
                            System.out.println(is3D ? "三维实体编码失败！" : "二维实体编码失败！");
                        }
                    }
                    recordset.update();
                    processBarDialog.setValue((index + 1) * 100 / recordCount);
                    index++;
                } while (recordset.moveNext());
            } finally {
                processBarDialog.setVisible(false);
                processBarDialog.dispose();

                recordset.close();
                datasetVector.close();
            }
        }).start();

        processBarDialog.setVisible(true);
        setVisible(false);
    }
}
